/*
**
**			Heroes IV
**	  Copyright 2001, The 3DO Company
**
**      adv_magic_gem.cpp
*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "adv_magic_gem.h"

#include "adventure_frame.h"
#include "adventure_map.h"
#include "adventure_sounds.h"
#include "adv_object_type.h"
#include "ai_value.h"
#include "army.h"
#include "basic_dialog.h"
#include "bitmap_group.h"
#include "bitmap_group_cache.h"
#include "bitmap_layer_window.h"
#include "dialog_magic_gem.h"
#include "game_window.h"
#include "hero.h"
#include "materials.h"
#include "music.h"
#include "object_registration.h"
#include "player.h"
#include "replace_keywords.h"
#include "simple_dialog.h"

static t_register_with_type<t_adv_magic_gem> k_registration( k_adv_object_magic_gem );

t_bitmap_group_cache k_pick_hero_bitmaps( "dialog.pick_hero" );

namespace
{
	float value_of_gem( t_creature_stack const& stack, t_magic_gem_type type )
	{
		t_hero const* hero = stack.get_const_hero();
		if (hero == NULL) 
			return 0.0f;

		switch ( type )
		{
			case k_gem_opal_of_magic :
				return ai_value_of_additional_spell_points( hero, 6 );
        
			case k_gem_sapphire_of_health :
				return ai_value_of_additional_hit_points( hero, 12 );
        
			case k_gem_ruby_of_offense :
				return ai_value_of_additional_damage( &stack, 2, 4 );
        
			case k_gem_emerald_of_speed :
				return ai_value_of_additional_speed( &stack, 2 );
			
			default:
				assert(false);
				return 0.0f;
		}
	}
}

/*
** Magic gems
*/
t_adv_magic_gem::t_adv_magic_gem(  std::string const& source, t_qualified_adv_object_type const& type )
          : t_stationary_adventure_object( source )
{

	m_gem_type = t_magic_gem_type( type.major_subtype() );
}

void t_adv_magic_gem::activate_trigger( t_army* army, t_adv_map_point const& point, 
		                           t_direction direction, t_adventure_frame* frame )
{
	t_creature_array& creatures = army->get_creatures();
	t_player* army_owner = army->get_owner();

	if (army_owner == NULL)
		return;

	bool is_human = !army_owner->is_computer();

	int                     i;
	t_hero*                 hero;
	t_hero*                 best_hero = NULL;
	std::vector<t_hero*>    heroes;
	bool				    any_heroes = false;
	float					best_value = 0.0f;

    // Check for heroes.
	for (i = 0; i < t_creature_array::k_size; i++)
	{
		t_creature_stack& stack = creatures[i];
		hero = stack.get_hero();
		if (hero == 0)
			continue;

		any_heroes = true;
		if (is_human)
			heroes.push_back( hero );
		else
		{
			float value = value_of_gem( stack, m_gem_type );
			if (value > best_value)
			{
				best_value = value;
				best_hero = hero;
			}
		}
	}

	if (!is_human)
	{
		if (best_hero == NULL)
			return;
		give_hero_gem_bonus( best_hero, m_gem_type );
		destroy();		
		return;
	}

    if (any_heroes == false)
    {
	    std::string status_text;

        // No heroes, gem is lost.
        status_text = get_text ("no heroes");
        if (yes_no_dialog( status_text, get_dialog_bottom( point ) ))
            destroy();
        return;
    }

    // Select hero for upgrade.
	t_counted_ptr<t_dialog_magic_gem> dialog_ptr;

	dialog_ptr = new t_dialog_magic_gem( frame );
	dialog_ptr->init_dialog( heroes, m_gem_type, *this );

    // Got benefit?
	t_sound_cache music = get_music_playing();
	stop_music();
	get_dialog_sound( k_dialog_sound_power_up )->play( get_sound_volume() );
	if (dialog_ptr->run_modal())
    {
        destroy();
    };
	play_music( music );
}

bool t_adv_magic_gem::read( std::streambuf&						stream, 
						    t_qualified_adv_object_type const&	type,
						    int									version )
{
    m_gem_type = t_magic_gem_type( get<t_uint32>( stream ));
    return true;
}

bool t_adv_magic_gem::write( std::streambuf& stream ) const
{
    put<t_uint32>( stream, m_gem_type );
    return true;
}

float t_adv_magic_gem::ai_value( t_adventure_ai const& ai, t_creature_array const& army, int move_cost ) const
{
	float best_value = 0.0f;
	for (int i = 0; i < t_creature_array::k_size; i++)
	{
		t_creature_stack const& stack = army[i];

		float value = value_of_gem( stack, m_gem_type );

		if (value > best_value)
			best_value = value;
	}
	return best_value;
}
